package com.demo.queue;

import java.util.Scanner;

/**
 * 环形队列 用数组模拟
 * 包括初始化队列、添加元素、获取元素、展示队列
 */
public class RoundQueue {
    public static void main(String[] args) {
        CycleQueue queue = new CycleQueue(3);
        Scanner scanner = new Scanner(System.in);
        boolean loop = true;
        String inStr = "";
        System.out.println();
        while (loop) {
            inStr = scanner.nextLine();
            switch (inStr) {
                case "s":
                    queue.showElement();
                    break;
                case "a":
                    queue.addElement(scanner.nextInt());
                    break;
                case "e":
                    scanner.close();
                    loop = false;
                    break;
                case "g":
                    queue.getElement();
                    break;
                case "t":
                    queue.totalElement();
                    break;
                case "h":
                    queue.headElement();
                    break;
                default:
                    break;
            }
        }
    }
}

class CycleQueue {
    private int maxSize;
    /**
     * front和real默认都为0
     */
    private int front;
    private int real;
    private int[] arr;

    public CycleQueue(int maxSize) {
        System.out.printf("初始化一个容量为 %d 的循环队列", maxSize);
        this.maxSize = maxSize;
        this.arr = new int[maxSize];
    }

    /**
     * 当队列为空时front==real，队列满时也是front==real
     * 所以，为了区别这两种情况，规定循环队列最多只能有maxSize-1个队列元素（空一个位置），当循环队列中只剩下一个空存储单元时，队列就满了
     * 这个空位置主要就是为了用来区分队空与队满的情况
     * @return
     */
    public boolean isFull() {
        return (real + 1) % maxSize == front;
    }

    /**
     * 是否为空队列
     * @return
     */
    public boolean isEmpty() {
        return front == real;
    }

    /**
     * 循环队列中的有效元素个数
     * @return
     */
    public int totalElement() {
        return (real + maxSize - front) % maxSize;
    }

    /**
     * 循环队列中的头元素
     */
    public void headElement() {
        if (isEmpty()) {
            throw new RuntimeException("队列为空");
        }
        System.out.printf("队列头元素为：%d\n", arr[front]);
    }

    /**
     * 从队列中取元素
     * @return
     */
    public int getElement() {
        if (isEmpty()) {
            throw new RuntimeException("队列为空");
        }
        int element = arr[front];
        System.out.printf("获取的元素为：%d", element);
        front = (front + 1) % maxSize;
        return element;
    }

    /**
     * 向队列中添加元素
     * @param element
     */
    public void addElement(int element) {
        if (isFull()) {
            System.out.println("队列已满");
            return;
        }
        arr[real] = element;
        real = (real + 1) % maxSize;
    }

    /**
     * 展示队列中的所有元素
     */
    public void showElement() {
        if (isEmpty()) {
            System.out.println("队列为空");
            return;
        }
        for (int i = front; i < front + totalElement(); i++) {
            System.out.printf("arr[%d]=%d\n", i % maxSize, arr[i % maxSize]);
        }
    }
}
